package com.atguigu.demojuc.chap01;

import java.util.concurrent.TimeUnit;

/**
 * 资源类
 */
class Phone{



    // 静态同步方法抢类对象锁。
    public static synchronized void sendSms(){ // short message service
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("短信");
    }

    //普通同步方法抢 实例对象锁
    public  synchronized void sendMail(){
        System.out.println("邮件");
    }


    //不需要锁就可以执行
    public void hello(){
        System.out.println("hello");
    }
}

/**
 * 研究锁到底是谁？ 任何一个对象都拥有一把锁。
 *      Class 类型对象
 *      普通实例对象
 *
 *
 * 看下面这段儿代码，回答多线程的8个问题：
 *
 * 1. 先访问短信，再访问邮件，先打印短信还是邮件
 * 短信
 * 邮件
 *  A线程有先天优势，先短信后邮件。抢同一个对象的锁，需要排队执行打印任务。
 *
 * 2. 停4秒在短信方法内，先打印短信还是邮件
 * 短信
 * 邮件
 *  A线程有先天优势,持有锁睡觉，先打印短信，再打印邮件。
 *
 * 3. 先访问短信，再访问hello方法，是先打短信还是hello
 *hello
 * 短信
 *
 * 打印短信需要加锁，但是由于睡觉，就后打印；  hello虽然不具有先天优势，后执行不睡觉，所以先打印出来。
 *
 * 4. 现在有两部手机，第一部发短信，第二部发邮件，先打印短信还是邮件
 *邮件
 * 短信
 * 两个手机两把锁。各抢各的锁。打印邮件不用睡觉，所以先打印；   打印短信睡觉所以后打印。
 *
 * 5. 两个静态同步方法，1部手机，先打印短信还是邮件
 * 短信
 * 邮件
 *  两个静态同步方法，去抢Phone.class对象的同一把锁。打印短信先执行，虽然睡觉，持有锁睡觉的，睡醒后打印短信，释放锁后，才再打印邮件。
 *
 * 6. 两个静态同步方法，2部手机，先打印短信还是邮件
 *短信
 * 邮件
 * 两个静态同步方法，去抢Phone.class对象的同一把锁（与创建几个实体对象无关）。打印短信先执行，虽然睡觉，持有锁睡觉的，睡醒后打印短信，释放锁后，才再打印邮件。
 *
 * 7. 1个静态同步方法，1个普通同步方法，1部手机，先打印短信还是邮件
 *邮件
 * 短信
 *
 * 静态同步方法抢Phone.class对象锁
 * 普通同步方法抢实例对象锁
 * 两个线程两把锁，各抢各的锁，相互不影响。邮件不睡觉所以先打印；短信睡觉所以后打印；
 *
 * 8. 1个静态同步方法，1个普通同步方法，2部手机，先打印短信还是邮件
 *邮件
 * 短信
 * 两个线程三把锁，静态同步方法抢Phone.class对象锁；   普通同步方法抢实例对象锁。各抢各的锁，相互不影响。邮件不睡觉所以先打印；短信睡觉所以后打印；
 */
public class Lock8 {
    public static void main(String[] args) {
        //Class clazz = Phone.class;
        Phone phone = new Phone(); //普通实例对象  对象头上锁的状态值
        Phone phone2 = new Phone(); //普通实例对象  对象头上锁的状态值

        new Thread(()->{
            phone.sendSms(); // Phone.sendSms();
        },"A").start();

        new Thread(()->{
            //phone.sendMail(); // Phone.sendMail();
            //phone.hello();
            phone2.sendMail();
        },"B").start();
    }
}
